package de.grosjohann.android.feuerwehr.location;

import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

public class MyLocation
  implements LocationListener {

  private static final String NAME = "MyLocation";

  private final LocationManager locationManager;

  private Timer timer;
  private ILocationResult locationResult;
  private boolean gpsEnabled = false;
  private boolean networkEnabled = false;

  public MyLocation(Context context) {
    locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
  }

  public boolean getLocation(ILocationResult result) {
    //I use LocationResult callback class to pass location value from MyLocation to user code.
    locationResult = result;

    //exceptions will be thrown if provider is not permitted.
    try {
      gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch (Exception ex) {
      Log.e(NAME, ex.getMessage(), ex);
    }
    try {
      networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch (Exception ex) {
      Log.e(NAME, ex.getMessage(), ex);
    }

    //don't start listeners if no provider is enabled
    if (!gpsEnabled && !networkEnabled) {
      return false;
    }

    if (gpsEnabled) {
      locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
    }
    if (networkEnabled) {
      locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
    }
    timer = new Timer();
    timer.schedule(new GetLastLocation(), 20000);

    return true;
  }

  @Override
  public void onLocationChanged(Location location) {
    timer.cancel();
    locationResult.gotLocation(location);
    locationManager.removeUpdates(this);
  }

  @Override
  public void onProviderDisabled(String provider) {
  }

  @Override
  public void onProviderEnabled(String provider) {
  }

  @Override
  public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
  }

  private class GetLastLocation
    extends TimerTask {

    @Override
    public void run() {
      locationManager.removeUpdates(MyLocation.this);

      Location netLoc = null;
      Location gpsLoc = null;
      if (gpsEnabled) {
        gpsLoc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
      }
      if (networkEnabled) {
        netLoc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
      }

      //if there are both values use the latest one
      if (gpsLoc != null && netLoc != null) {
        if (gpsLoc.getTime() > netLoc.getTime()) {
          locationResult.gotLocation(gpsLoc);
        } else {
          locationResult.gotLocation(netLoc);
        }
        return;
      }

      if (gpsLoc != null) {
        locationResult.gotLocation(gpsLoc);
        return;
      }
      if (netLoc != null) {
        locationResult.gotLocation(netLoc);
        return;
      }

      locationResult.gotLocation(null);
    }
  }
}
